package com.oa.code;

import java.awt.image.BufferedImage;
import java.io.File;
import java.util.HashMap;
import java.util.Map;

import javax.imageio.ImageIO;

import org.apache.log4j.Logger;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.Binarizer;
import com.google.zxing.BinaryBitmap;
import com.google.zxing.DecodeHintType;
import com.google.zxing.EncodeHintType;
import com.google.zxing.FormatException;
import com.google.zxing.LuminanceSource;
import com.google.zxing.MultiFormatReader;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.Result;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.common.HybridBinarizer;

/**
 * 生成二维码或者条形码工具类
 */
public class CodeUtil {
    private static String[] arr = { "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z" };
    private static Logger logger = Logger.getLogger(CodeUtil.class);
    private static String format = "png";

    /**
     * 生成二维码（QR类型）
     * 
     * @param content 
     *            二维码文本内容
     * @param file
     *            生成的路径（文件路径）
     * @return 返回文件路径加文件全名称
     */
    public static String getQRCode(String content, String file) {
        try {
            if (null == content || content.equals("")) {
                logger.error("CodeUtil.class-->getQRCode()-->content is null");
            }
            int width = 300;
            int height = 300;
            HashMap<EncodeHintType, String> hints = new HashMap<EncodeHintType, String>();
            hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
            // 二维码的格式是BarcodeFormat.QR_CODE qr类型二维码 BarcodeFormat.DATA_MATRIX dm码
            BitMatrix qrc = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, width, height, hints);
            File out = new File(file + "/" + getFileName());
            // 生成二维码图片
            WriteBitMatricToFile.writeBitMatricToFile(qrc, format, out);
            WriteBitMatricToFile.parseCode(out);
            logger.info(out.getAbsolutePath());
            return out.getAbsolutePath();
        } catch (Exception e) {
            logger.error(e.getMessage());
            return null;
        }
    }

    /**
     * 生成条形码
     * 
     * @param content
     *            条形码文本内容
     * @param file
     *            生成的路径（文件路径）
     * @return 返回文件路径加文件全名称
     */
    public static String getBarCode(String content, String file) {
        try {
            if (null == content || content.equals("")) {
                logger.error("CodeUtil.class-->getQRCode()-->content is null");
                return null;
            }
            int len = content.trim().length();
            if (len != 12 && len != 13) {
                logger.error("CodeUtil.class-->getQRCode()-->content length fail (12 or 13,fact " + len + ")");
                return null;
            }
            int width = 105;
            int height = 50;
            HashMap<EncodeHintType, String> hints = new HashMap<EncodeHintType, String>();
            hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
            // 条形码的格式是 BarcodeFormat.EAN_13
            BitMatrix bc = new MultiFormatWriter().encode(content, BarcodeFormat.EAN_13, width, height, hints);
            File out = new File(file + "/" + getFileName());
            // 输出图片
            WriteBitMatricToFile.writeBitMatricToFile(bc, format, out);
            WriteBitMatricToFile.parseCode(out);
            // 记录日志
            logger.info(out.getAbsolutePath());
            return out.getAbsolutePath();
        } catch (Exception e) {
            logger.error(e.getMessage());
            return null;
        }
    }
    //条形码校验
    public static boolean checkStandardUPCEANChecksum(CharSequence s) throws FormatException {
		int length = s.length();
		if (length == 0) {
			return false;
		}

		int sum = 0;
		for (int i = length - 2; i >= 0; i -= 2) {
			int digit = (int) s.charAt(i) - (int) '0';
			if (digit < 0 || digit > 9) {
				throw FormatException.getFormatInstance();
			}
			sum += digit;
		}
		sum *= 3;
		for (int i = length - 1; i >= 0; i -= 2) {
			int digit = (int) s.charAt(i) - (int) '0';
			if (digit < 0 || digit > 9) {
				throw FormatException.getFormatInstance();
			}
			sum += digit;
		}
		return sum % 10 == 0;
	}

    private static String getFileName() {
        // 随机生成26以内的正整数
        int next = (int) Math.floor(Math.random() * 26);
        // 生成文件的名称，当前时间毫秒数+一个随机字母+后缀
        return System.currentTimeMillis() + arr[next] + "." + format;
    }

    /**
     * 解析二维码中的信息
     * 
     * @param filePath
     * @return 二维码中文本
     */
    public static String parseQRCode(String filePath) {
        String content = "";
        try {
            File file = new File(filePath);
            BufferedImage image = ImageIO.read(file);
            LuminanceSource source = new BufferedImageLuminanceSource(image);
            Binarizer binarizer = new HybridBinarizer(source);
            BinaryBitmap binaryBitmap = new BinaryBitmap(binarizer);
            Map<DecodeHintType, Object> hints = new HashMap<DecodeHintType, Object>();
            hints.put(DecodeHintType.CHARACTER_SET, "UTF-8");
            MultiFormatReader formatReader = new MultiFormatReader();
            Result result = formatReader.decode(binaryBitmap, hints);

            System.out.println("result 为：" + result.toString());
            System.out.println("resultFormat 为：" + result.getBarcodeFormat());
            System.out.println("resultText 为：" + result.getText());
            // 设置返回值
            content = result.getText();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return content;
    }
    
    
}